#include "chart_manager.h"
#include "database_manager.h"
#include <QSqlError>
#include <QDateTime>
#include <QValueAxis>
#include <QBarCategoryAxis>

ChartManager::ChartManager(QObject *parent) : QObject(parent) {
}

QChart* ChartManager::createSalesChart(const QDate &startDate, const QDate &endDate) {
    auto salesData = getSalesDataByDate(startDate, endDate);
    
    auto *series = new QBarSeries();
    auto *set = new QBarSet("销售额");
    
    QStringList categories;
    for (auto it = salesData.begin(); it != salesData.end(); ++it) {
        *set << it.value();
        categories << it.key();
    }
    
    series->append(set);
    
    auto *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("销售统计");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    
    auto *axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);
    
    auto *axisY = new QValueAxis();
    axisY->setLabelFormat("%.2f");
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
    
    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);
    
    return chart;
}

QChart* ChartManager::createProductSalesRankingChart(const QDate &startDate, const QDate &endDate) {
    auto rankingData = getProductSalesRanking(startDate, endDate);
    
    auto *series = new QBarSeries();
    auto *set = new QBarSet("销量");
    
    QStringList categories;
    int count = 0;
    for (auto it = rankingData.begin(); it != rankingData.end() && count < 10; ++it, ++count) {
        *set << it.value();
        categories << it.key();
    }
    
    series->append(set);
    
    auto *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("产品销量排行 Top 10");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    
    auto *axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);
    
    auto *axisY = new QValueAxis();
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
    
    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);
    
    return chart;
}

QChart* ChartManager::createInventoryDistributionChart() {
    auto inventoryData = getInventoryDistribution();
    
    auto *series = new QPieSeries();
    
    for (auto it = inventoryData.begin(); it != inventoryData.end(); ++it) {
        series->append(it.key(), it.value());
    }
    
    series->setLabelsVisible(true);
    series->setLabelsPosition(QPieSlice::LabelOutside);
    
    auto *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("库存分布");
    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignRight);
    
    return chart;
}

QChart* ChartManager::createProfitAnalysisChart(const QDate &startDate, const QDate &endDate) {
    auto profitData = getProfitData(startDate, endDate);
    
    auto *series = new QLineSeries();
    series->setName("利润率 (%)");
    
    QStringList categories;
    for (auto it = profitData.begin(); it != profitData.end(); ++it) {
        qreal revenue = it.value().first;  // 收入
        qreal cost = it.value().second;    // 成本
        qreal profitRate = (revenue - cost) / revenue * 100;
        if (revenue > 0) {
            series->append(categories.size(), profitRate);
            categories << it.key();
        }
    }
    
    auto *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("利润率分析");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    
    auto *axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);
    
    auto *axisY = new QValueAxis();
    axisY->setLabelFormat("%.1f%%");
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
    
    return chart;
}

QChart* ChartManager::createMonthlySalesTrendChart(int year) {
    auto monthlyData = getMonthlySalesData(year);
    
    auto *series = new QLineSeries();
    series->setName("月销售额");
    
    QStringList months = {"1月", "2月", "3月", "4月", "5月", "6月", 
                         "7月", "8月", "9月", "10月", "11月", "12月"};
    
    for (int i = 0; i < months.size(); ++i) {
        series->append(i, monthlyData.value(months[i], 0));
    }
    
    auto *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle(QString("%1年销售趋势").arg(year));
    chart->setAnimationOptions(QChart::SeriesAnimations);
    
    auto *axisX = new QBarCategoryAxis();
    axisX->append(months);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);
    
    auto *axisY = new QValueAxis();
    axisY->setLabelFormat("%.2f");
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
    
    return chart;
}

// 私有方法实现
QMap<QString, qreal> ChartManager::getSalesDataByDate(const QDate &startDate, const QDate &endDate) {
    QMap<QString, qreal> salesData;
    
    QSqlQuery query;
    query.prepare("SELECT DATE(operation_time) as date, SUM(total_amount) as total "
                  "FROM sales "
                  "WHERE operation_time BETWEEN ? AND ? "
                  "GROUP BY DATE(operation_time) "
                  "ORDER BY date");
    query.addBindValue(startDate.toString("yyyy-MM-dd"));
    query.addBindValue(endDate.toString("yyyy-MM-dd 23:59:59"));
    
    if (query.exec()) {
        while (query.next()) {
            QString date = query.value(0).toDate().toString("MM-dd");
            qreal total = query.value(1).toDouble();
            salesData[date] = total;
        }
    }
    
    return salesData;
}

QMap<QString, int> ChartManager::getProductSalesRanking(const QDate &startDate, const QDate &endDate) {
    QMap<QString, int> rankingData;
    
    QSqlQuery query;
    query.prepare("SELECT p.name, SUM(s.quantity) as total_quantity "
                  "FROM sales s "
                  "JOIN products p ON s.product_id = p.id "
                  "WHERE s.operation_time BETWEEN ? AND ? "
                  "GROUP BY p.name "
                  "ORDER BY total_quantity DESC");
    query.addBindValue(startDate.toString("yyyy-MM-dd"));
    query.addBindValue(endDate.toString("yyyy-MM-dd 23:59:59"));
    
    if (query.exec()) {
        while (query.next()) {
            QString productName = query.value(0).toString();
            int quantity = query.value(1).toInt();
            rankingData[productName] = quantity;
        }
    }
    
    return rankingData;
}

QMap<QString, int> ChartManager::getInventoryDistribution() {
    QMap<QString, int> inventoryData;
    
    QSqlQuery query;
    query.exec("SELECT category, SUM(stock_quantity) as total_stock "
               "FROM products "
               "GROUP BY category");
    
    while (query.next()) {
        QString category = query.value(0).toString();
        if (category.isEmpty()) category = "未分类";
        int stock = query.value(1).toInt();
        inventoryData[category] = stock;
    }
    
    return inventoryData;
}

QMap<QString, QPair<qreal, qreal>> ChartManager::getProfitData(const QDate &startDate, const QDate &endDate) {
    QMap<QString, QPair<qreal, qreal>> profitData;
    
    QSqlQuery query;
    query.prepare("SELECT p.name, SUM(s.total_amount) as revenue, SUM(s.quantity * p.cost) as cost "
                  "FROM sales s "
                  "JOIN products p ON s.product_id = p.id "
                  "WHERE s.operation_time BETWEEN ? AND ? "
                  "GROUP BY p.name");
    query.addBindValue(startDate.toString("yyyy-MM-dd"));
    query.addBindValue(endDate.toString("yyyy-MM-dd 23:59:59"));
    
    if (query.exec()) {
        while (query.next()) {
            QString productName = query.value(0).toString();
            qreal revenue = query.value(1).toDouble();
            qreal cost = query.value(2).toDouble();
            profitData[productName] = qMakePair(revenue, cost);
        }
    }
    
    return profitData;
}

QMap<QString, qreal> ChartManager::getMonthlySalesData(int year) {
    QMap<QString, qreal> monthlyData;
    
    QStringList months = {"1月", "2月", "3月", "4月", "5月", "6月", 
                         "7月", "8月", "9月", "10月", "11月", "12月"};
    
    for (int month = 1; month <= 12; ++month) {
        QDate startDate(year, month, 1);
        QDate endDate(year, month, startDate.daysInMonth());
        
        QSqlQuery query;
        query.prepare("SELECT SUM(total_amount) as total "
                      "FROM sales "
                      "WHERE operation_time BETWEEN ? AND ?");
        query.addBindValue(startDate.toString("yyyy-MM-dd"));
        query.addBindValue(endDate.toString("yyyy-MM-dd 23:59:59"));
        
        if (query.exec() && query.next()) {
            qreal total = query.value(0).toDouble();
            monthlyData[months[month-1]] = total;
        }
    }
    
    return monthlyData;
}